package com.kritsana_ding.startrax;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;

public class VDO extends Activity implements LocationListener,
		Camera.ErrorCallback, SurfaceHolder.Callback, OnClickListener {

	public static final String TAG = "VideoRecording";

	Handler handler = new Handler();
	public Camera mCamera;
	public CameraPreview mPreview;
	public MediaRecorder mMediaRecorder;
	public Button captureButton;
	public boolean isRecording = false;
	public List<Size> sizes;

	public LocationManager lm;
	public TextView textView;
	public String time = "00:00";

	public Handler handler1 = new Handler();
	public Handler handler2 = new Handler();
	public Handler handler3 = new Handler();

	public int count_1 = 0;

	public Runnable task1 = new Runnable() {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			if (count_1 == 2) {
				if (prepareVideoRecorder()) {
					mMediaRecorder.start();
					setCaptureButtonText("Stop");

					isRecording = true;
				} else {
					releaseMediaRecorder();

				}
			} else if (count_1 == 23) {
				count_1 = 0;
				if (isRecording) {
					mMediaRecorder.stop();
					// TODO Auto-generated method stub
					releaseMediaRecorder();
					mCamera.lock();
					setCaptureButtonText("Capture");
					isRecording = false;
				}
			}

			String min = Integer.toString(count_1 / 60);
			String sec = Integer.toString(count_1 % 60);

			if (min.length() == 1) {
				min = "0" + min;
			}

			if (sec.length() == 1) {
				sec = "0" + sec;
			}
			setText(min + ":" + sec);

			handler1.postDelayed(this, 1000);
			count_1++;
		}
	};

	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.vdo);
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
		lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		textView = (TextView) findViewById(R.id.textView_VDO_GPS);

		if (mCamera == null) {
			mCamera = getCameraInstance();
			mPreview = new CameraPreview(this, mCamera);
		}

		else {
			mCamera.release();
			mCamera = getCameraInstance();
			mPreview = new CameraPreview(this, mCamera);
		}

		int i = R.id.videoview;
		Object o = this.findViewById(i);
		FrameLayout preview = (FrameLayout) o;
		preview.addView(mPreview);

		Camera.Parameters params = mCamera.getParameters();
		params.set("cam_mode", 1);
		mCamera.setParameters(params);

		sizes = params.getSupportedPreviewSizes();

		// Add a listener to the Capture button
		captureButton = (Button) findViewById(R.id.mybutton);
		captureButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				if (isRecording) {
					mMediaRecorder.stop();
					// TODO Auto-generated method stub

					releaseMediaRecorder(); // release the MediaRecorder object
					mCamera.lock();
					setCaptureButtonText("Capture");
					isRecording = false;
				}

				else {
					// initialize video camera
					if (prepareVideoRecorder()) {
						mMediaRecorder.start();
						setCaptureButtonText("Stop");

						isRecording = true;
					} else {
						releaseMediaRecorder();

					}
				}
			}
		});

		handler1.postDelayed(task1, 10);
	}

	public void setCaptureButtonText(String s) {
		captureButton.setText(s);
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// The Surface has been created, now tell the camera where to draw the
		// preview.
		try {
			mCamera.setPreviewDisplay(holder);
			mCamera.startPreview();

		} catch (IOException e) {
			Log.d(TAG, "Error setting camera preview: " + e.getMessage());
			Toast.makeText(this, "Device is not supported!", Toast.LENGTH_LONG)
					.show();
		}
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// TODO Auto-generated method stub
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
	}

	public boolean prepareVideoRecorder() {
		mMediaRecorder = new MediaRecorder();
		mCamera.unlock();
		mMediaRecorder.setCamera(mCamera);
		//CamcorderProfile camcorderProfile_HQ = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
		//mMediaRecorder.setProfile(camcorderProfile_HQ);
		mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
		mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
		mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
		mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
		mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
		mMediaRecorder.setVideoSize(1280, 720);
		mMediaRecorder.setVideoFrameRate(64);
		mMediaRecorder.setOutputFile(getOutputMediaFile("movie"));
		mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());

		try {
			mMediaRecorder.prepare();
		} catch (IllegalStateException e) {
			Log.d(TAG,"IllegalStateException preparing MediaRecorder: " + e.getMessage());
			Toast.makeText(this, "Device is not supported!", Toast.LENGTH_LONG).show();
			releaseMediaRecorder();
			return false;
		} catch (IOException e) {
			Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
			Toast.makeText(this, "Device is not supported!", Toast.LENGTH_LONG).show();
			releaseMediaRecorder();
			return false;
		}
		return true;
	}

	@Override
	public void onClick(View v) {

	}

	@Override
	protected void onPause() {
		super.onPause();
		if (isRecording) {
			mMediaRecorder.stop();
			releaseMediaRecorder();
			mCamera.lock();
			setCaptureButtonText("RECORD");
			isRecording = false;
		} else {
			releaseMediaRecorder();
		}
		// releaseCamera();

	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (isRecording) {
			mMediaRecorder.stop();
			releaseMediaRecorder();
			mCamera.lock();
			setCaptureButtonText("RECORD");
			isRecording = false;
		} else {
			releaseMediaRecorder();
			releaseCamera();
		}
	}

	public void releaseMediaRecorder() {
		if (mMediaRecorder != null) {
			mMediaRecorder.reset(); 
			mMediaRecorder.release();
			mMediaRecorder = null;
			mCamera.lock();
		}
	}

	public void releaseCamera() {
		if (mCamera != null) {
			mCamera.release();
			mCamera = null;
		}
	}

	public Camera getCameraInstance() {
		Camera c = null;
		try {
			c = Camera.open();
		} catch (Exception e) {			
		}
		return c;
	}

	public Camera open() {
		return Camera.open();
	}

	@Override
	public void onError(int error, Camera camera) {
		// TODO Auto-generated method stub
		if (error == Camera.CAMERA_ERROR_SERVER_DIED
				|| error == Camera.CAMERA_ERROR_UNKNOWN) {
			releaseCamera();
			finish();
			Toast.makeText(this, "Camera has died", Toast.LENGTH_LONG).show();
		}
	}

	public Size getMaxSupportedVideoSize() {
		int maximum = sizes.get(0).width;
		int position = 0;
		for (int i = 0; i < sizes.size() - 1; i++) {
			if (sizes.get(i).width > maximum) {
				maximum = sizes.get(i).width; // new maximum
				position = i - 1;
			}
		}
		if (position == 0) {
			int secondMax = sizes.get(1).width;
			position = 1;
			for (int j = 1; j < sizes.size() - 1; j++) {
				if (sizes.get(j).width > secondMax) {
					secondMax = sizes.get(j).width; // new maximum
					position = j;
				}

			}
		}

		return sizes.get(position);
		// end method max

	}

	@SuppressLint("SimpleDateFormat")
	public static String getOutputMediaFile(String sufix) {

		String mediaFile;
		File mediaStorageDir = new File(Environment.getExternalStorageDirectory(), "/VideoLogger");
		if (!mediaStorageDir.exists()) {
			if (!mediaStorageDir.mkdirs()) {
				Log.d("VideoLogger", "failed to create directory");
				return null;
			}
		}
		String timeStamp = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss").format(new Date());
		if (!sufix.equals("movie")) {
			mediaFile = mediaStorageDir.getPath() + File.separator + ""+ timeStamp + "_" + sufix + ".txt";
		} else {
			mediaFile = mediaStorageDir.getPath() + File.separator + ""+ timeStamp + ".mp4";

		}

		return mediaFile;
	}

	@Override
	public void onLocationChanged(Location loc) {
		// TODO Auto-generated method stub
		try {
			String lat = Double.toString(loc.getLatitude());
			String lon = Double.toString(loc.getLongitude());
			String spe = Double.toString(loc.getSpeed());

			setText("Latitude : " + lat + "\n" + "Longitude : " + lon + "\n"
					+ "Speed: " + spe);

		} catch (Exception e) {
			// TODO: handle exception
			setText("No Data");
		}

	}

	@Override
	public void onProviderDisabled(String provider) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onProviderEnabled(String provider) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) {
		// TODO Auto-generated method stub

	}

	public void setText(String txt) {
		textView.setText(txt);
	}

}
